package com.elinshaw;

import java.util.LinkedList;

/**
 * @author elinShaw
 */
public class LinkedRunnableQueue implements RunnableQueue {

    /**
     * 任务队列最大容量
     */
    private final int limit;

    /**
     * 若任务队列满了执行拒绝策略
     */
    private final DenyPolicy denyPolicy;

    /**
     *
     */
    private final ThreadPool threadPool;

    /**
     * 任务队列
     * 双向循环列表
     */
    private final LinkedList<Runnable> runnableList = new LinkedList<>();

    public LinkedRunnableQueue(int limit, DenyPolicy denyPolicy, ThreadPool threadPool) {
        this.limit = limit;
        this.denyPolicy = denyPolicy;
        this.threadPool = threadPool;
    }


    @Override
    public void offer(Runnable runnable) {
        synchronized (runnableList) {
            if (runnableList.size() >= limit) {
                //无法容纳新的任务执行拒绝策略
                denyPolicy.reject(runnable, threadPool);
            } else {
                //加队尾
                runnableList.addLast(runnable);
                runnableList.notifyAll();
            }
        }
    }

    @Override
    public Runnable take() throws InterruptedException {
        synchronized (runnableList) {
            while (runnableList.isEmpty()) {
                try {
                    //没有任务则挂起等待新的任务加入
                    runnableList.wait();
                } catch (InterruptedException e) {
                    throw e;
                }
            }
            //任务队列头部移除一个任务
            return runnableList.removeFirst();
        }
    }

    @Override
    public int size() {
        synchronized (runnableList) {
            //返回任务队列任务数量
            return runnableList.size();
        }
    }

}
